#pragma once

#include "stdafx.h"

/*
This source code has been written to bridge the vtk memory structure vtk::vtkImage with the OpenCV GPU memory structure cv::cuda::GpuMat.
The basic pipeline for this is: 
vtkImage -> cv::Mat -> cv::cuda::GpuMat
*/

class vtkOpenCVBridge
{
public:
	vtkOpenCVBridge (vtkSmartPointer<vtkImageData> vtkImage, std::vector<cv::Mat> vector_cvMat, int dims[3])
	{
		m_imageData = vtkImage;
		m_vectorCVMat = vector_cvMat;
		*m_dimensions = *dims;
	}
	vtkOpenCVBridge (vtkSmartPointer<vtkImageData> vtkImage)
	{
		m_imageData = vtkImage;
		m_imageData->GetDimensions(m_dimensions);
	}
	vtkOpenCVBridge (std::vector<cv::Mat> vector_cvMat)
	{
		m_vectorCVMat = vector_cvMat;
		m_imageData = vtkSmartPointer<vtkImageData>::New();
		m_dimensions[1] = m_vectorCVMat[0].rows;
		m_dimensions[0] = m_vectorCVMat[0].cols;
		m_dimensions[2] = (int)m_vectorCVMat.size();
	}
	//vtkOpenCVBridge (std::vector<cv::gpu::GpuMat> vector_gpuMat)
	vtkOpenCVBridge (std::vector<cv::cuda::GpuMat> vector_gpuMat)
	{
		m_vectorGPUMat = vector_gpuMat;
		vtkOpenCVBridge::vector_gpuMatToCvMat(/*m_vectorGPUMat, m_vectorCVMat*/);
		m_dimensions[1] = m_vectorCVMat[0].rows;
		m_dimensions[0] = m_vectorCVMat[0].cols;
		m_dimensions[2] = (int)m_vectorCVMat.size();
	}

	vtkSmartPointer<vtkImageData> OpenCVtoVTK ();
	//std::vector<cv::gpu::GpuMat> VTKtoOpenCV ();
	std::vector<cv::cuda::GpuMat> VTKtoOpenCV ();

	~vtkOpenCVBridge()
	{
		//delete [] m_dimensions;
		m_vectorCVMat.clear();
		m_vectorGPUMat.clear();
		m_imageData->Delete();
	}

	cv::Mat vectorToConcat();
	std::vector <cv::Mat> concatToVector(cv::Mat& input_concat);

private:
	vtkSmartPointer<vtkImageData> m_imageData;
	std::vector<cv::Mat> m_vectorCVMat;
	cv::Mat m_concat;
	//std::vector<cv::gpu::GpuMat> m_vectorGPUMat;
	std::vector<cv::cuda::GpuMat> m_vectorGPUMat;

	int m_dimensions[3];
	void vector_cvMatTogpuMat ();
	void vector_gpuMatToCvMat ();

};